<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>Vue 实例</title>
    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>

    <style>
        body,
        html {
            margin: 0 auto;
            padding: 0;
        }

        * {
            list-style: none;
            list-style-type: none;
            margin: 0 auto;
            padding: 0;
        }


        #treeData ul {
            padding-left: 30px;
        }

        #treeData li {
            line-height: 30px;
        }


        #treeData li.open>.node_line>.node_icon {
            transform: rotate(90deg);
            display: inline-block;
            transition: transform 0.2s linear;
            transform-origin: center, center;
        }


        #treeData li .node_icon {
            width: 16px;
            height: 16px;
            line-height: 16px;
            display: inline-block;
            cursor: pointer;
            transition: transform 0.2s linear;
            user-select: none;
        }

        #treeData li .node_icon.node_icon_has {
            background: url(img/arrow.png);
            background-position: -3px 16px;
        }


        #treeData .node_icon:hover {
            cursor: pointer;
        }

        #treeData .node_name {
            padding: 2px 4px;
            cursor: pointer;
            color: #333;
        }


        #treeData .node_name:hover {
            cursor: pointer;
            background-color: lightseagreen;
            color: white;
        }

        #treeData li>ul {
            display: none;
            height: 0px;
        }

        #treeData li.open>ul {
            display: block;
            height: auto;
            transition: height 0.2s linear;
        }
    </style>

</head>

<body>
    <div id="treeData">

        <ul>
            <tree v-for="item in treeData" ref="my_tree_ref" v-bind:node="item"></tree>
        </ul>

        <button onclick="loadData()">展开tree后,点击模拟来数据</button>

    </div>

    <script>


        var myTreeData = [{
            mtKey: '1',
            name: '科达科技',
            children: [{
                mtKey: '21',
                name: 'web前端开发',
                children: [{
                    mtKey: '211',
                    name: '开发一组',
                    children: []
                },
                {
                    mtKey: '222',
                    name: '开发二组',
                    children: []

                }
                ]
            },
            {
                mtKey: '22',
                name: 'Java后台',
                children: []

            }]
        }
        ];

        var myTreeData2 = [{
            mtKey: '1',
            name: '科达科技',
            children: [{
                mtKey: '21',
                name: 'web前端开发',
                children: [{
                    mtKey: '211',
                    name: '开发一组',
                    children: []
                },
                {
                    mtKey: '333',
                    name: '开发三组',
                    children: []

                }
                ]
            },
            {
                mtKey: '22',
                name: 'Java后台',
                children: []

            }]
        },
        {
            mtKey: '2',
            name: '万豪酒店',
            children: []
        }, {
            mtKey: '3',
            name: '如家酒店',
            children: []
        }];

        Vue.component('tree', {
            template: `
                <li :class="{'open':node.open}"  @click.stop.prevent="handlerItemClick(node)">        
                    <div class="node_line">
                        <span v-if="node.children&&node.children.length>0" class="node_icon node_icon_has"  @click.stop.prevent="handlerExpandIconClick(node)">
                        
                        </span>
                        <span v-else class="node_icon" >
                            
                        </span>
                        <span class="node_name"> {{node.name}}</span>
                        </div>
                    <ul>
                        <tree v-if="node.children&&node.children.length>0" :node="item"  v-for="item in node.children"></tree>
                    </ul>
                </li>
            `,
            props: ["node"],
            mounted: function () {
                var that = this;
                setInterval(function () {
                    that.$forceUpdate()
                }, 500);
            },
            name: "tree", methods: {
                handlerItemClick: function (node) {
                    console.log(node);
                },
                handlerExpandIconClick: function (node) {
                    console.log(node);
                    node.open = !node.open;
                    if (!node.open) {
                        this.setChildrenClosed(node.children)
                    }

                },
                setChildrenClosed(children) {
                    if (children == undefined || children.length == 0) {
                        return;
                    }
                    children.forEach((item) => {
                        item.open = false;
                        this.setChildrenClosed(item.children)
                    })
                }
            }
        })


        //构造open字段  接口不能有该key
        function AddMyKey(arr) {
            arr.forEach((item) => {
                item['open'] = false;
                return AddMyKey(item.children)
            })
            return arr;
        }

        //加入open字段
        myTreeData = AddMyKey(myTreeData);

        // 创建根实例
        var vueApp = new Vue({
            name: 'treeData',
            el: '#treeData',
            data: {
                treeData: []
            },
            created: function () {
                this.treeData = myTreeData;
            },
            mounted: function () {
                var that = this;
                setInterval(function () {
                    that.$forceUpdate()
                }, 500);
            },
            methods: {
                reload() {
                    this.$forceUpdate()
                }
            }
        })


        function loadData() {
            $.extend(true, myTreeData, myTreeData2);
            vueApp.reload();
        }


    </script>

</body>

</html>